package icu.sehnen.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import icu.sehnen.common.CommonUser;
import icu.sehnen.common.result.CommonResult;
import icu.sehnen.user.entity.MyPage;
import icu.sehnen.user.entity.Permission;
import icu.sehnen.user.entity.User;
import icu.sehnen.user.feign.SendUserInfo2RabbitFeign;
import icu.sehnen.user.mapper.UserMapper;
import icu.sehnen.user.service.IRoleService;
import icu.sehnen.user.service.IUserService;
import icu.sehnen.user.utils.jwt.JwtTokenUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.beans.Transient;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
 * <p>
 * 后台用户表 服务实现类
 * </p>
 *
 * @author icu.sehnen
 * @since 2021-04-27
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    PasswordEncoder passwordEncoder;
    @Autowired
    JwtTokenUtil jwtTokenUtil;
    @Autowired
    IRoleService roleService;
    @Autowired
    private SendUserInfo2RabbitFeign sendUserInfo2RabbitFeign;
    @Override
    public User getUserByName(String name)  {

        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("username",name);
        User user=userMapper.selectOne(queryWrapper);
        user.setLoginTime(getNow());
        QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("id",user.getId());
        userMapper.update(user,objectQueryWrapper);
     //   Assert.isTrue(user!=null,"您输入的账户不存在");
         return   user;
    }

    private Date  getNow() {
        Date date = new Date();
        SimpleDateFormat format0 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = format0.format(date);
        Date time1= null;
        try {
            time1 = format0.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return time1;
    }

    //    代码写的不规范
    @Override
    public List<Permission> getPermissionsByUserId(Long id) {
//        if(!redisTemplate.hasKey("permission:list")){
             List<Permission> permissionList=userMapper.getPermissionByUserId(id) ;
         return permissionList;
             //            redisTemplate.opsForList().leftPushAll("permission:list", permissionList);
//        }
//        return    redisTemplate.opsForList().range("permission:list", 0, -1);

    }

    @Override
    public String login(User user) {
        String username = user.getUsername();
        Assert.notNull(username,"账号必须不能为空");
        String password = user.getPassword();
        Assert.notNull(password,"密码必须不能为空");
        User userByName = getUserByName(username);
        boolean matches = passwordEncoder.matches(password, userByName.getPassword());
        if(matches){
            List<Permission> permissionsByUserId = getPermissionsByUserId(userByName.getId());
            // 将权限list 转化为set形式
            HashSet<Permission> permissions = new HashSet<>(permissionsByUserId);
            // 将权限设置到用户实例中
            userByName.setAuthorities(permissions);
            return jwtTokenUtil.generateToken(userByName);
        }
        return null;
    }

    @Override
    public IPage<User> getUsers(Long  pageNum, Long  pageSize,User user,String searchTime) {
        MyPage myPage = new MyPage(pageNum, pageSize);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.like(!StringUtils.isBlank(user.getUsername()),"username",user.getUsername());
        if(searchTime != ""){
            String [] StartAndEndTime = searchTime.split(",");
            queryWrapper.between(!StringUtils.isBlank(searchTime), "login_time",StartAndEndTime[0],StartAndEndTime[1]);
        }
        return  userMapper.selectPage(myPage,queryWrapper);
    }

    @Override
    public Integer   switchStatus(Long id,Integer status ) {
        QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("id",id);
        User user=  User.builder().status(status).build();
        return   userMapper.update(user,objectQueryWrapper);

    }



    @Override
    public Integer register(User user) {
        user.setCreateTime( getNow());
       Integer res =  userMapper.insert(user);
        CommonUser commonUser=new CommonUser();
        if(res ==1 ){
            commonUser.setUsername(user.getUsername());
            commonUser.setEmail(user.getEmail());
            commonUser.setPassword(user.getPassword());
            commonUser.setPhone(user.getPhone());
            sendUserInfo2RabbitFeign.sendDirectMessage(commonUser);
        }

        return res;
    }

    @Override
    public User findUserById(Long id) {
        QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("id",id);
        User user = userMapper.selectOne(objectQueryWrapper);
        user.setRoleList(roleService.getIRoleIdsByUserId(user.getId()));
        return  user;
    }

    @Override
    public Integer deleteUserById(Long id) {
        UpdateWrapper updateWrapper =new UpdateWrapper();
         updateWrapper.eq("id",id);
        return  userMapper.delete(updateWrapper);

    }

    @Override
    public List<Permission> getMenusByUserId(Long id) {
       List<Permission> rootMenu = getPermissionsByUserId(id);
        return buildMenuTree(rootMenu,0L);
    }

    @Override
    @Transient
    public Integer editUser(User user) {
             roleService.addRoleforUserId(user.getRoleList(),user.getId());
           QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
           objectQueryWrapper.eq("id",user.getId());
      return   userMapper.update(user,objectQueryWrapper);
    }

    @Override
    @Transient
    public void addUser(User user) {
        user.setLoginTime(getNow());
        user.setCreateTime(getNow());
        userMapper.insert(user);
        roleService.addRoleforUserId(user.getRoleList(),user.getId());
    }

    private List<Permission> buildMenuTree(List<Permission> menuList, Long pid) {
        List<Permission> treeList = new ArrayList<>();
        menuList.forEach(menu -> {
            if (pid.equals(menu.getPid())) {
                menu.setChildren(buildMenuTree(menuList, menu.getId()));
                treeList.add(menu);
            }
        });
        return treeList;
    }

    @Override
    public CommonResult checkAccessToUri(String uri, String username) {
        User userByName = getUserByName(username);
        List<Permission> permissionsByUserId = getPermissionsByUserId(userByName.getId());
        boolean b = permissionsByUserId.stream().anyMatch(Permission -> org.apache.commons.lang.StringUtils.equals(Permission.getPath(), uri));
        return b?CommonResult.success(true):CommonResult.failed();
    }
}
